/**
 * 表达式转换工具方法
 * @param code
 */
export function translate (code) {
    let data = []
    let tmp_code = code.replace(/\s/g,'')
    let tmp = []
    let vari = tmp_code.split(/["]+[^"]*["]+|[']+[^']*[']+|\*\*|\+|-|\*|\/|\(|\)|\?|>[=]|<[=]|={2}|:|&{2}|\|{2}|\{|\}|=|%|\.\/|\.\*|,/g)
    let ops = tmp_code.match(/["]+[^"]*["]+|[']+[^']*[']+|\*\*|\+|-|\*|\/|\(|\)|\?|>[=]|<[=]|={2}|:|&{2}|\|{2}|\{|\}|=|%|\.\/|\.\*|,/g)
    for (let i = 0,len = ops.length; i < len; i++) {
        if (vari[i] != '') {
            tmp.push(vari[i])
        }
        if (ops[i] != '') {
            tmp.push(ops[i])
        }
    }
    tmp.push(vari[ops.length])
    for (let i = 0; i < tmp.length; i++){
        let item = tmp[i]
        if(/\*\*|\+|-|\*|\/|%|\.\/|\.\*/.test(tmp[i])) {
            let top = data.pop()
            let trans = '__replace__(' + top + ',\'' + tmp[i] + '\','
            data.push(trans)
        }else{
            if (')' == tmp[i]) {
                let trans0 = tmp[i]
                let top0 = data.pop()
                while (top0 != '(') {
                    trans0 = top0 + trans0
                    top0 = data.pop()
                }
                trans0 = top0 + trans0
                let pre = data[data.length - 1]
                while(/[_\w]+[\.]?[_\w]+/.test(pre)
                && !/^__replace__\(/.test(pre)
                && pre != undefined) {
                    pre = data.pop()
                    trans0 = pre + trans0
                    pre = data[data.length - 1]
                }
                pre = data[data.length - 1]
                while(pre != undefined
                && /^__replace__\(/.test(pre)){
                    pre = data.pop()
                    trans0 = pre + trans0 + ')'
                    pre = data[data.length - 1]
                }
                data.push(trans0)
            }else {
                let pre = data[data.length - 1]
                let trans1 = tmp[i]
                while(pre != undefined
                && /^__replace__\(/.test(pre)
                && !/\*\*|\+|-|\*|\/|\(|\?|>[=]|<[=]|={2}|:|&{2}|\|{2}|\{|=|\}|%|\.\/|\.\*/.test(item)
                && !/^__replace__\(/.test(item)) {
                    if(tmp[i + 1] == undefined){
                        pre = data.pop()
                        trans1 = pre + trans1 + ')'
                        break;
                    }else{
                        pre = data.pop()
                        trans1 = pre + trans1 + ')'
                        pre = data[data.length - 1]
                    }

                }
                data.push(trans1)

            }
        }
    }
    let result = ''
    data.forEach((value, key, own) => {
        result += value
    })
    return result
}

/**
 * 代码块转换工具
 * @param block
 * @returns {string}
 */

export function translate_process (block) {
    let codes = block.split('\n')
    for(let i = 0; i < codes.length; i++) {
        if(/\*\*|\+|-|\*|\/|%|\.\/|\.\*/g.test(codes[i])){
            if (codes[i].indexOf('return ') != -1) {
                let ret_index = codes[i].indexOf('return ') + 7
                codes[i] = codes[i].substring(0,ret_index) + translate(codes[i].substring(ret_index))
            }else {
                let eq_index = codes[i].indexOf('=') + 1
                codes[i] = codes[i].substring(0,eq_index) + translate(codes[i].substring(eq_index))
            }
        }
    }
    return codes.join('\n')
}

/**
 * 类代码块转换工具
 * @param name
 * @param block
 * @returns {string}
 */
export function translate_block (name , block) {
    let codes = block.split('\n')
    let reg = new RegExp('^' + name + '$')
    console.log(reg.source)
    codes[0] = codes[0].replace(name,'function')
    for(let i = 1; i < codes.length; i++) {
        if (codes[i].indexOf('//') != -1) {
            codes[i] = codes[i].substring(0,codes[i].indexOf('//'))
        }
        if(/\*\*|\+|-|\*|\/|%|\.\/|\.\*/g.test(codes[i])){
            if (codes[i].indexOf('return ') != -1) {
                let ret_index = codes[i].indexOf('return ') + 7
                codes[i] = codes[i].substring(0,ret_index) + translate(codes[i].substring(ret_index))
            }else {
                let eq_index = codes[i].indexOf('=') + 1
                codes[i] = codes[i].substring(0,eq_index) + translate(codes[i].substring(eq_index))
            }
        }
    }
    return 'return ' + codes.join('\n')
}

/**
 * 转换方法
 * @param a
 * @param op
 * @param b
 * @returns {*}
 * @private
 */
export function __replace__(a,op,b){
    if(typeof(a) != 'object' && typeof(b) != 'object'){
        return new Function('a','b','return a' + op + 'b')(a,b)
    }
    if(!Object.getPrototypeOf(a).isPrototypeOf(b)
        && Object.getPrototypeOf(b).isPrototypeOf(a)){
        throw '不同类型的对象不能使用四则运算'
    }
    let target = null
    if (Object.getPrototypeOf(a).isPrototypeOf(b)) {
        target = new Function('return ' + b.__proto__.constructor.name)()
    }
    if (Object.getPrototypeOf(b).isPrototypeOf(a)) {
        target =  new Function('return ' + a.__proto__.constructor.name)()
    }
    if (op == '+') {
        if (target.__add__ != undefined) {
            return target.__add__(a, b)
        }else {
            throw target.toString() +'\n未定义__add__方法'
        }
    }else if(op == '-') {
        if (target.__plus__ != undefined) {
            return target.__plus__(a, b)
        }else {
            throw target.toString() + '\n未定义__plus__方法'
        }
    }else if(op == '*') {
        if (target.__multiply__ != undefined) {
            return target.__multiply__(a, b)
        }else {
            throw target.toString() + '\n未定义__multiply__方法'
        }
    } else if (op == '/') {
        if (target.__divide__ != undefined) {
            return target.__divide__(a, b)
        }else {
            throw target.toString() + '\n未定义__divide__方法'
        }
    } else if (op == '%') {
        if (target.__mod__ != undefined) {
            return target.__mod__(a, b)
        }else {
            throw target.toString() + '\n未定义__mod__方法'
        }
    } else if(op == '.*') {
        if (target.__dot_multiply__ != undefined) {
            return target.__dot_multiply__(a, b)
        }else {
            throw target.toString() + '\n未定义__dot_multiply__方法'
        }
    } else if(op == './') {
        if (target.__dot_divide__ != undefined) {
            return target.__dot_divide__(a, b)
        }else {
            throw target.toString() + '\n未定义__dot_divide__方法'
        }
    } else if(op == '**') {
        if (target.__power__ != undefined) {
            return target.__power__(a, b)
        }else {
            throw target.toString() + '\n未定义__power__方法'
        }
    }else {
        throw op + '运算符无法识别'
    }
}